"""K8s资源Markdown写入器基础接口模块"""

from abc import ABC, abstractmethod
from typing import Dict, Any, Optional, Union
import logging
import os
from src.utils.markdown_builder import MarkdownBuilder

class Writer(ABC):
    """
    K8s资源Markdown写入器基础接口
    所有具体写入器必须实现write方法
    """
    
    def __init__(self, config_manager=None, logger: Optional[logging.Logger] = None):
        """
        初始化写入器
        
        Args:
            config_manager: 配置管理器，可选
            logger: 日志记录器，可选
        """
        self.logger = logger or logging.getLogger(__name__)
        self.config_manager = config_manager
        
        # 从配置中加载Markdown相关选项
        self.top_heading_level = 1
        self.include_raw_content = False
        self.generate_toc = True
        self.use_section_numbers = True
        self.link_style = 'relative'
        self.table_display = 'auto'
        
        # 字段显示配置
        self.show_namespace = True
        self.show_annotations = True
        self.show_labels = True
        self.specific_fields = {}
        
        if self.config_manager:
            self._load_markdown_config()
    
    def _load_markdown_config(self):
        """加载Markdown相关配置"""
        try:
            # 加载基本Markdown选项
            self.top_heading_level = self.config_manager.get('markdown', 'top_heading_level', default=1)
            self.include_raw_content = self.config_manager.get('markdown', 'include_raw_content', default=False)
            self.generate_toc = self.config_manager.get('markdown', 'generate_toc', default=True)
            self.use_section_numbers = self.config_manager.get('markdown', 'use_section_numbers', default=True)
            self.link_style = self.config_manager.get('markdown', 'link_style', default='relative')
            self.table_display = self.config_manager.get('markdown', 'table_display', default='auto')
            
            # 加载通用字段显示配置
            common_fields = self.config_manager.get('markdown', 'fields', 'common', default={})
            if common_fields:
                self.show_namespace = common_fields.get('show_namespace', True)
                self.show_annotations = common_fields.get('show_annotations', True)
                self.show_labels = common_fields.get('show_labels', True)
            
            # 加载特定资源类型的字段显示配置
            self.specific_fields = self.config_manager.get('markdown', 'fields', 'specific', default={})
        except Exception as e:
            self.logger.warning(f"加载Markdown配置失败: {str(e)}")
    
    @abstractmethod
    def write(self, data: Dict[str, Any], output_path: str) -> None:
        """
        将提取的K8s资源信息写入Markdown文件
        
        Args:
            data: 提取的结构化信息
            output_path: 输出文件路径
        """
        pass
    
    def create_markdown_builder(self) -> MarkdownBuilder:
        """
        创建一个新的Markdown构建器实例
        
        Returns:
            MarkdownBuilder: 配置好的Markdown构建器
        """
        md = MarkdownBuilder(use_section_numbers=self.use_section_numbers)
        
        # 如果配置启用了章节编号，确保它被激活
        if self.use_section_numbers:
            md.enable_section_numbers()
        else:
            md.disable_section_numbers()
            
        return md
    
    def should_show_field(self, resource_type: str, field_name: str, default: bool = True) -> bool:
        """
        检查是否应该显示指定字段
        
        Args:
            resource_type: 资源类型
            field_name: 字段名称
            default: 默认值
            
        Returns:
            是否应该显示
        """
        # 检查特定资源类型的配置
        if resource_type in self.specific_fields:
            resource_config = self.specific_fields[resource_type]
            field_key = f"show_{field_name}"
            if field_key in resource_config:
                return resource_config[field_key]
        
        # 通用字段检查
        if field_name == 'namespace':
            return self.show_namespace
        elif field_name == 'annotations':
            return self.show_annotations
        elif field_name == 'labels':
            return self.show_labels
        
        return default
    
    def ensure_output_directory(self, output_path: str) -> bool:
        """
        确保输出目录存在
        
        Args:
            output_path: 输出文件路径
            
        Returns:
            是否成功创建或目录已存在
        """
        dir_path = os.path.dirname(output_path)
        if not os.path.exists(dir_path):
            try:
                os.makedirs(dir_path, exist_ok=True)
                self.logger.debug(f"创建输出目录: {dir_path}")
                return True
            except Exception as e:
                self.logger.error(f"创建输出目录失败: {dir_path}, 错误: {str(e)}")
                return False
        return True
    
    def write_markdown(self, content: Union[str, MarkdownBuilder], output_path: str) -> None:
        """
        写入Markdown文件
        
        Args:
            content: Markdown内容或MarkdownBuilder实例
            output_path: 输出文件路径
        """
        # 将MarkdownBuilder转换为字符串
        if isinstance(content, MarkdownBuilder):
            content = str(content)
            
        if not self.ensure_output_directory(output_path):
            raise IOError(f"无法创建输出目录: {os.path.dirname(output_path)}")
        
        try:
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(content)
            self.logger.info(f"Markdown文件已生成: {output_path}")
        except Exception as e:
            self.logger.error(f"写入Markdown文件失败: {output_path}, 错误: {str(e)}")
            raise
    
    def add_toc_if_needed(self, md: MarkdownBuilder, sections: list) -> None:
        """
        如果配置启用了目录生成，则添加目录
        
        Args:
            md: Markdown构建器实例
            sections: 节标题列表
        """
        if self.generate_toc and sections:
            md.line("## 目录")
            md.toc(sections)
            md.newline()
    
    def add_raw_content_if_needed(self, md: MarkdownBuilder, data: Dict[str, Any]) -> None:
        """
        如果配置启用了原始内容显示，则添加原始内容
        
        Args:
            md: Markdown构建器实例
            data: 资源数据
        """
        if self.include_raw_content and "raw_content" in data:
            md.header("原始内容", 2)
            
            with md.code_block("yaml"):
                import yaml
                yaml_content = yaml.dump(data["raw_content"], default_flow_style=False)
                md.line(yaml_content)
    
    # 以下是为了向后兼容的方法，建议在新代码中使用MarkdownBuilder
    
    def format_dict_as_table(self, data: Dict[str, Any], title: str = "") -> str:
        """
        将字典格式化为Markdown表格（向后兼容，推荐使用MarkdownBuilder）
        
        Args:
            data: 字典数据
            title: 表格标题，可选
            
        Returns:
            Markdown格式的表格
        """
        md = self.create_markdown_builder()
        
        if title:
            md.header(title, 3)
        
        md.dict_table(data)
        return str(md)
    
    def create_section(self, title: str, content: str = "", level: int = 2) -> str:
        """
        创建Markdown节（向后兼容，推荐使用MarkdownBuilder）
        
        Args:
            title: 节标题
            content: 节内容，可选
            level: 标题级别(1-6)
            
        Returns:
            Markdown格式的节
        """
        md = self.create_markdown_builder()
        md.header(title, level)
        
        if content:
            md.paragraph(content)
        
        return str(md)
    
    def create_table_of_contents(self, sections: list) -> str:
        """
        创建目录（向后兼容，推荐使用MarkdownBuilder）
        
        Args:
            sections: 节标题列表
            
        Returns:
            Markdown格式的目录
        """
        md = self.create_markdown_builder()
        md.toc(sections)
        return str(md)